using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Pampa.CRUD.Exceptions;
using System.Xml;

namespace Pampa.CRUD.Configuration
{
    /// <summary>
    /// Esta clase representa la definicion de un grupo de campos a editar en el CRUD de una entidad
    /// </summary>
    public abstract class Group
    {
        string id;
        string title;
        List<Item> items;
        string permissionRequired;
        GroupInitialState initialState;

        private List<GroupLink> groupLinks;

        public Group()
        {
            initialState = GroupInitialState.Expanded;
            items = new List<Item>();
            groupLinks = new List<GroupLink>();
        }

        #region Properties

        public String Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        public string PermissionRequired
        {
            get { return permissionRequired; }
            set { permissionRequired = value; }
        }

        public List<Item> Items
        {
            get { return items; }
        }

        public Item this[string id]
        {
            get
            {
                int i = 0;
                while ((i < this.Items.Count) && (this.Items[i].Id != id))
                {
                    i++;
                }

                if (i < this.Items.Count)
                    return this.Items[i];
                else
                    return null;
            }
        }

        public GroupInitialState InitialState
        {
            get { return initialState; }
            set { initialState = value; }
        }

        public List<GroupLink> GroupLinks
        {
            get { return groupLinks; }
            set { groupLinks = value; }
        }

        #endregion

        #region Public Functions

        public static Group FromXml(XmlNode node)
        {
            Assembly assembly = Assembly.GetAssembly(typeof(Group));
            Group group = (Group)assembly.CreateInstance("Pampa.CRUD.Configuration." + node.Name);
            group.LoadXml(node);

            return group;
        }

        public virtual void LoadXml(XmlNode node)
        {
            this.Id = node.Attributes["Id"].Value;
            this.Title = node.Attributes["Title"].Value;

            if (node.Attributes["PermissionRequired"] != null)
                this.PermissionRequired = node.Attributes["PermissionRequired"].Value;

            if (node.Attributes["InitialState"] != null)
                this.InitialState = (GroupInitialState)Enum.Parse(typeof(GroupInitialState), node.Attributes["InitialState"].Value);

            XmlNode nodeItems = ConfigurationManager.GetChildNode(node, "Items");

            if (nodeItems == null || nodeItems.ChildNodes.Count == 0)
            {
                throw new ConfigurationException("No puede definirse un grupo sin items");
            }

            foreach (XmlNode childNode in nodeItems.ChildNodes)
            {
                Item item = Item.LoadFromXml(childNode); 
                Items.Add(item);
            }
        }

        #endregion
    }
}
